/**
 * 认证中间件
 * 用于验证用户身份和权限
 */

const { authenticate } = require('../services/auth.service');
const { logWarning, logError } = require('../logger');

/**
 * 验证JWT令牌中间件
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一步函数
 */
async function authenticateToken(req, res, next) {
  try {
    // 从请求头获取令牌
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

    if (!token) {
      logWarning('访问被拒绝：缺少访问令牌');
      return res.status(401).json({ 
        success: false, 
        message: '访问被拒绝：缺少访问令牌' 
      });
    }

    // 验证令牌
    const user = await authenticate(token);

    if (!user) {
      logWarning('访问被拒绝：令牌无效或已过期');
      return res.status(403).json({ 
        success: false, 
        message: '访问被拒绝：令牌无效或已过期' 
      });
    }

    // 将用户信息附加到请求对象
    req.user = user;
    next();
  } catch (error) {
    logError('认证中间件错误', { error: error.message });
    return res.status(500).json({ 
      success: false, 
      message: '服务器内部错误' 
    });
  }
}

/**
 * 验证管理员权限中间件
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一步函数
 */
async function authorizeAdmin(req, res, next) {
  try {
    // 首先验证令牌
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      logWarning('访问被拒绝：缺少访问令牌');
      return res.status(401).json({ 
        success: false, 
        message: '访问被拒绝：缺少访问令牌' 
      });
    }

    // 验证用户身份
    const user = await authenticate(token);

    if (!user) {
      logWarning('访问被拒绝：令牌无效或已过期');
      return res.status(403).json({ 
        success: false, 
        message: '访问被拒绝：令牌无效或已过期' 
      });
    }

    // 检查是否为管理员
    if (user.role !== 'admin') {
      logWarning('访问被拒绝：权限不足', { userId: user.id, role: user.role });
      return res.status(403).json({ 
        success: false, 
        message: '访问被拒绝：权限不足' 
      });
    }

    // 将用户信息附加到请求对象
    req.user = user;
    next();
  } catch (error) {
    logError('管理员权限验证中间件错误', { error: error.message });
    return res.status(500).json({ 
      success: false, 
      message: '服务器内部错误' 
    });
  }
}

/**
 * 可选认证中间件
 * 如果提供了令牌则验证，否则继续执行
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一步函数
 */
async function optionalAuth(req, res, next) {
  try {
    // 从请求头获取令牌
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];

    if (!token) {
      // 没有令牌，继续执行
      return next();
    }

    // 验证令牌
    const user = await authenticate(token);

    if (!user) {
      // 令牌无效，继续执行（视为匿名用户）
      return next();
    }

    // 将用户信息附加到请求对象
    req.user = user;
    next();
  } catch (error) {
    logError('可选认证中间件错误', { error: error.message });
    // 出错时也继续执行
    next();
  }
}

module.exports = {
  authenticateToken,
  authorizeAdmin,
  optionalAuth
};